﻿using System;
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Caliburn.Micro;
using JY.Common.Extensions;
using JY.Common.Helpers;
using JY.IOC;
using JY.Wpf.Core.Events;
using JY.Wpf.Core.Tools;

namespace JY.Wpf.Core.ViewModelBases
{
    /// <summary>
    /// ViewModel基类
    /// </summary>
    public class ViewModelBase : Conductor<object>, IHandle<FlipperEvent>
    {
        #region # 变量

        #endregion

        #region # 构造器
        /// <summary>
        /// 构造器
        /// </summary>
        protected ViewModelBase()
        {

        }
        #endregion

        #region # 属性

        #region 唯一标识——Guid Id

        /// <summary>
        /// 唯一标识
        /// </summary>
        public readonly Guid Id = Guid.NewGuid();
        #endregion

        #region 标题——string Title

        private string _title;
        /// <summary>
        /// 标题
        /// </summary>
        public string Title
        {
            get { return this._title; }
            set { this._title = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #region 是否显示遮罩——bool IsBusy
        private bool _isBusy;
        /// <summary>
        /// 是否显示遮罩
        /// </summary>
        public bool IsBusy
        {
            get { return this._isBusy; }
            set { this._isBusy = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #region 显示遮罩的内容——object BusyContent
        private object _busyContent;
        /// <summary>
        /// 显示遮罩的内容
        /// </summary>
        public object BusyContent
        {
            get { return this._busyContent; }
            set { this._busyContent = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #region 是否切换页面——bool IsFlipped
        private bool _isFlipped;
        /// <summary>
        /// 是否切换页面
        /// </summary>
        public bool IsFlipped
        {
            get { return this._isFlipped; }
            set { this._isFlipped = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #region 事件——IEventAggregator EventAggregator
        /// <summary>
        /// 事件
        /// </summary>
        public IEventAggregator EventAggregator
        {
            get
            {
                return ResolveMediator.Resolve<IEventAggregator>();
            }
        }
        #endregion

        #region 页面视图——object View
        private object _view;
        /// <summary>
        /// 页面视图
        /// </summary>
        public object View
        {
            get { return this._view; }
            set { this._view = value; base.NotifyOfPropertyChange(); }
        }
        #endregion

        #endregion

        #region # Event方法

        #region # 翻转内容——void Handle(FlipperEvent eventData)
        /// <summary>
        /// 翻转内容
        /// </summary>
        public virtual Task HandleAsync(FlipperEvent eventData, CancellationToken cancellationToken)
        {
            if (!EventAggregatorExtension.CheckCanPublishSubscriber(this, typeof(IHandle<FlipperEvent>)))
            {
                return Task.FromResult(false);
            }
            this.IsFlipped = eventData.IsFlipped;
            return Task.CompletedTask;
        }
        #endregion

        #endregion

        #region # 方法

        #region # 页面加载完成——void OnViewLoaded(object view)
        /// <summary>
        /// 页面加载完成
        /// </summary>
        /// <param name="view"></param>
        protected override void OnViewLoaded(object view)
        {
            base.OnViewLoaded(view);
            this.View = view;
            this.OnInit();
        }
        #endregion

        #region # 初始化页面——void OnInit()
        /// <summary>
        /// 初始化页面
        /// </summary>
        public virtual void OnInit()
        {

        } 
        #endregion

        #region # 重置页面——void Reset()
        /// <summary>
        /// 重置页面
        /// </summary>
        public virtual void Reset()
        {

        }
        #endregion

        #region # 挂起繁忙状态——void Busy(string busyContent = "执行中...")
        /// <summary>
        /// 挂起繁忙状态
        /// </summary>
        /// <param name="busyContent">繁忙状态内容</param>
        public virtual void Busy(string busyContent = "执行中...")
        {
            Application.Current.BeginInvoke(() =>
            {
                this.IsBusy = true;
                this.BusyContent = busyContent;
                this.BusyOperation();
            });
        }
        #endregion

        #region # 释放繁忙状态——void Idle()
        /// <summary>
        /// 释放繁忙状态
        /// </summary>
        public virtual void Idle()
        {
            Application.Current.BeginInvoke(() =>
            {
                this.IsBusy = false;
                this.BusyOperation();
            });
        }
        #endregion

        #region # 繁忙状态操作——void BusyOperation()
        /// <summary>
        /// 繁忙状态操作
        /// </summary>
        public virtual void BusyOperation()
        {

        }

        #endregion

        #endregion

        #region # 生命周期相关

        #region # 页面激活——Task OnActivateAsync(CancellationToken cancellationToken)
        /// <summary>
        /// 页面激活
        /// </summary>
        protected override Task OnActivateAsync(CancellationToken cancellationToken)
        {
            return base.OnActivateAsync(cancellationToken);
        }
        #endregion

        #region # 页面失活——Task OnDeactivateAsync(bool close, CancellationToken cancellationToken)
        /// <summary>
        /// 页面失活
        /// </summary>
        protected override Task OnDeactivateAsync(bool close, CancellationToken cancellationToken)
        {
            this.EventAggregator.UnSubscribe(this);
            //查找属性为ViewModelBase的进行处理
            Type type = this.GetType();
            var propertyInfos = type.GetProperties().Where(x => x.CustomAttributes.Any()).ToList();
            foreach (var propertyInfo in propertyInfos)
            {
                var viewModelPropertyAttribute = propertyInfo.GetCustomAttribute<ViewModelPropertyAttribute>();
                if (viewModelPropertyAttribute == null) continue;
                if (viewModelPropertyAttribute.IsList)
                {
                    var viewmodels = propertyInfo.GetValue(this) as IList;
                    if (viewmodels == null) continue;
                    foreach (var viewmodel in viewmodels)
                    {
                        if (viewmodel is ViewModelBase viewModelBase)
                        {
                            viewModelBase.Deactivate();
                        }
                    }
                }
                else
                {
                    if (propertyInfo.GetValue(this) is ViewModelBase viewModelBase)
                    {
                        viewModelBase.Deactivate();
                    }
                }
            }
            base.OnDeactivateAsync(close, cancellationToken);
            //释放内存
            FlushMemoryHelper.FlushMemory();
            return Task.CompletedTask;
        }
        #endregion

        #region # 页面失活——void Deactivate()
        /// <summary>
        /// 页面失活
        /// </summary>
        public virtual void Deactivate()
        {
            this.OnDeactivateAsync(true, CancellationToken.None);
        }
        #endregion
        #endregion

        #region 获取页面——object GetView(object context = null)
        /// <summary>
        /// 获取页面
        /// </summary>
        /// <param name="context">页面</param>
        /// <returns></returns>
        public override object GetView(object context = null)
        {
            return this.View ?? base.GetView(context);
        }
        #endregion
    }
}
